// the extent server implementation

#include "extent_server.h"
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

extent_server::extent_server() {
/*initialize stuff here, make sure to create
 *an entry for the root of the filesystem*/
  extent_protocol::attr init_attr;
  time_t now = time(NULL);

  init_attr.atime = now;
  init_attr.mtime = now;
  init_attr.ctime = now;
  init_attr.size = 0;

  attrmap[0x1] = init_attr;
  contmap[0x1] = "";
}

int extent_server::put(extent_protocol::extentid_t id, std::string buf, int &t)
{
  int old_file = 0;
  time_t old_ctime;
  printf("extent_server put\n");

  //check if id is in map
  if (contmap.find(id) != contmap.end() && attrmap.find(id)!=attrmap.end()){
    old_ctime= (attrmap[id]).ctime;
    contmap.erase(contmap.find(id));
    attrmap.erase(attrmap.find(id));
    old_file = 1;
  }
  
  contmap[id] = buf;
  
  printf("id: %llu \n", id);
  printf("buf: %s\n", buf.c_str());

  // define create, access, modified time as current time
  extent_protocol::attr attributes;
  time_t current_time = time(NULL);

  attributes.atime = current_time;
  attributes.mtime = current_time;

  if (old_file == 1){
    attributes.ctime = current_time;
  } else {
    attributes.ctime = current_time;
  }

  attributes.size = buf.length();
  attrmap[id] = attributes;

  return extent_protocol::OK;	
  
}


int extent_server::get(extent_protocol::extentid_t id, std::string &buf)
{
  printf("extent_server get\n");
  if((contmap.find(id) != contmap.end()) && (attrmap.find(id) != attrmap.end())){

    buf = contmap[id];

    printf("this is buf in get: %s\n", buf.c_str());
    
    extent_protocol::attr new_attr;
    extent_protocol::attr attributes = attrmap[id];

    time_t current_time = time(NULL);


    new_attr.atime = current_time;
    new_attr.ctime = attributes.ctime;
    new_attr.size = attributes.size;
    new_attr.mtime = attributes.mtime;

    attrmap.erase(attrmap.find(id));
      
    attrmap[id] = new_attr;
      
    return extent_protocol::OK;

  }else {
    return extent_protocol::NOENT;
  }
}

int extent_server::getattr(extent_protocol::extentid_t id, extent_protocol::attr &a)
{
  if(attrmap.find(id) != attrmap.end()){
	a = attrmap[id];
	return extent_protocol::OK;
  }else{
	return extent_protocol::NOENT;
  }

}

int extent_server::remove(extent_protocol::extentid_t id, int &)
{
  printf("ES _-- remove id: %llu\n", id);

  // check if id is in map and is not the root
  if(contmap.find(id) != contmap.end()){
    printf("extent_server remove\n");
    attrmap.erase(id);
    contmap.erase(id);
    return extent_protocol::OK;
  }
  return extent_protocol::NOENT;
}

